﻿using System;
using System.Linq;
using WebChat.Models;
using System.Collections.Generic;
using System.Net;
using System.Collections.Specialized;

namespace WebChat.Models
{
    /// <summary>
    /// Brukerens metoder, se klasse for forklaring av disse.
    /// </summary>
    public interface IUserRepository
    {
        IQueryable<aspnet_User> showAllUsers();
        void updateUser(aspnet_User user);
        List<aspnet_User> usersInChatroom(int chatId);
        List<UsersInChatroom> getUsersInChatroom(int chatId);
        bool isUserInChat(int chatId, Guid userId);
        void addUserToChat(UsersInChatroom u);
        void removeUserInChat(UsersInChatroom u);
        UsersInChatroom getUserInChat(int chatId, Guid userId);
        void deleteUser(aspnet_User user);
        Guid getUserId(string name);
        Permitted_user showPermittedUser(string userId);
        List<aspnet_User> showCurrentUsers(List<Permitted_user> userId);
        List<Permitted_user> showUserWithChatroom(int chatroom);
        List<Permitted_user> showYourPermittedRooms(Guid userId);
        List<aspnet_User> showUsersNotInChatroom(List<Permitted_user> userId);
        void addPermittedUsers(Permitted_user user);
        void deletePermittedUsers(Permitted_user user);
        string getUserName(Guid userId);
        aspnet_User getOwner(Chatroom room);
        void addRole(aspnet_UsersInRole usrInRole);
        void removeRole(aspnet_UsersInRole usrInRole);
        aspnet_User showUser(Guid id);
        aspnet_UsersInRole getUserRoles(aspnet_User usr);
    }

    public class UserRepository : IUserRepository
    {
        private ChannelDataClassesDataContext db;

        /// <summary>
        /// Kontruktør
        /// </summary>
        public UserRepository() 
        {
            db = new ChannelDataClassesDataContext();
        }

        /// <summary>
        /// Søker i databasen å returnerer alle brukere
        /// </summary>
        /// <returns>alle brukere</returns>
        public IQueryable<aspnet_User> showAllUsers() 
        {           
            return db.aspnet_Users;
        }

        /// <summary>
        /// Henter ut alle brukere som ikke er inputbruker
        /// </summary>
        /// <param name="userId">BrukerId på bruker du ikke ønsker i den returnerte lista</param>
        /// <returns></returns>
        public IEnumerable<aspnet_User> showOtherUsers(Guid userId)
        {
            List<aspnet_User> users = (from u in db.aspnet_Users
                                       where u.UserId != userId
                                       select u).ToList();
            return users;
        }

        /// <summary>
        /// Returnerer en bruker fra databasen
        /// </summary>
        /// <param name="id">Bruker-ID</param>
        /// <returns></returns>
        public aspnet_User showUser(Guid id)
        {
            aspnet_User user = (from o in db.aspnet_Users
                                where o.UserId.Equals(id)
                                select o).FirstOrDefault();
            return user;
        }

        /// <summary>
        /// Oppdaterer en bruker
        /// </summary>
        /// <param name="user">en bruker</param>
        public void updateUser(aspnet_User user)
        {
            db.SubmitChanges();
        }

        /// <summary>
        /// Returnerer en liste over brukere som er innlogget i chatroom i form av aspnet_user
        /// </summary>
        /// <param name="chatId">Chatroom ID</param>
        /// <returns></returns>
        public List<aspnet_User> usersInChatroom(int chatId)
        {
            List<Guid> userIds = (from u in db.UsersInChatrooms
                                  where u.chatId == chatId
                                  select u.userId).ToList();
            List<aspnet_User> users = new List<aspnet_User>();

            foreach (Guid id in userIds)
            {
                users.Add(showUser(id));
            }
            return users;

        }

        /// <summary>
        /// Returnerer en liste over brukere som er innlogget i chatroom i form av UsersInChatroom
        /// </summary>
        /// <param name="chatId"></param>
        /// <returns></returns>
        public List<UsersInChatroom> getUsersInChatroom(int chatId)
        {
            List<UsersInChatroom> users = (from u in db.UsersInChatrooms
                                           where u.chatId == chatId
                                           select u).ToList();
            return users;
        }

        /// <summary>
        /// returnerer true om bruker er innlogget i chatroom
        /// </summary>
        /// <param name="chatId">Chatroom ID</param>
        /// <param name="userId">Bruker-ID</param>
        /// <returns></returns>
        public bool isUserInChat(int chatId, Guid userId) 
        {
            List<Guid> users = (from u in db.UsersInChatrooms//Henter alle brukere i chatroom
                                where u.chatId == chatId
                                select u.userId).ToList();
            foreach (Guid g in users)
            {
                if (g == userId)//Skjekker om noen av brukerne er inputbruker
                    return true;
            }
            return false;
        }

        /// <summary>
        /// Legger til bruker i chatroom.
        /// </summary>
        /// <param name="u">UsersInChatroom tabell</param>
        public void addUserToChat(UsersInChatroom u)
        {
                db.UsersInChatrooms.InsertOnSubmit(u);
                db.SubmitChanges();
        }

        /// <summary>
        /// Fjerner bruker fra aktuell chatroom
        /// </summary>
        /// <param name="u">UsersInChatroom tabell</param>
        public void removeUserInChat(UsersInChatroom u)
        {
            db.UsersInChatrooms.DeleteOnSubmit(u);
            db.SubmitChanges();
        }

        /// <summary>
        /// Returnerer UsersInChatroom kollonnen til inputbruker
        /// </summary>
        /// <param name="chatId">Chatroom ID</param>
        /// <param name="userId">Bruker ID</param>
        /// <returns></returns>
        public UsersInChatroom getUserInChat(int chatId, Guid userId)
        {
            UsersInChatroom uInC = (from u in db.UsersInChatrooms
                                    where u.chatId == chatId
                                    where u.userId == userId
                                    select u).FirstOrDefault();
            return uInC;
        }

        /// <summary>
        /// Sletter en bruker
        /// </summary>
        /// <param name="user">en bruker</param>
        public void deleteUser(aspnet_User user)
        {
            db.aspnet_Users.DeleteOnSubmit(user);
            db.SubmitChanges();
        }

        /// <summary>
        /// Henter brukerid basert på navn
        /// </summary>
        /// <param name="name">navn på en bruker</param>
        /// <returns>en bruker id</returns>
        public Guid getUserId(string name)
        {
            aspnet_User user = (from o in db.aspnet_Users
                                where o.UserName == name
                                select o).FirstOrDefault();
            return user.UserId;
        }

        /// <summary>
        /// Henter ut en spesifikk bruker i Permitt_user tabellen
        /// </summary>
        /// <param name="userId">bruker id</param>
        /// <returns>en bruker fra Permitted_user</returns>
        public Permitted_user showPermittedUser(string userId)
        {
            Permitted_user user = (from u in db.Permitted_users
                                   where u.UserId == Guid.Parse(userId)
                                   select u).FirstOrDefault();

            return user;
        }

        /// <summary>
        /// Henter brukere fra brukertabellen
        /// </summary>
        /// <param name="userId">liste over Permitted_user</param>
        /// <returns>Returnerer brukere fra aspnet_User tabellen</returns>
        public List<aspnet_User> showCurrentUsers(List<Permitted_user> userId)
        {
            List<aspnet_User> users = new List<aspnet_User>();
            foreach (Permitted_user id in userId)
            {
                aspnet_User user = (from u in db.aspnet_Users
                                    where id.UserId == u.UserId
                                    select u).FirstOrDefault();
                users.Add(user);
            }
            return users;
        }

        /// <summary>
        /// Henter ut alle brukere som har tilgang til ett rom
        /// </summary>
        /// <param name="chatroom">rom navn</param>
        /// <returns>liste over tilatte brukere</returns>
        public List<Permitted_user> showUserWithChatroom(int chatroom)
        {
            List<Permitted_user> users = (from u in db.Permitted_users
                                         where u.Chatroom == chatroom
                                         select u).ToList();
            return users;
        }

        /// <summary>
        /// Henter alle rom du har tilgang på
        /// </summary>
        /// <param name="userId">bruker id</param>
        /// <returns></returns>
        public List<Permitted_user> showYourPermittedRooms(Guid userId)
        {
            List<Permitted_user> user = (from u in db.Permitted_users
                                         where u.UserId == userId
                                         select u).ToList();
            return user;
        }

        /// <summary>
        /// Henter alle brukere untatt de du har tilatt
        /// </summary>
        /// <param name="userId">liste med Permitted_user</param>
        /// <returns>liste fra aspnet_User tabellen</returns>
        public List<aspnet_User> showUsersNotInChatroom(List<Permitted_user> userId)
        {

            List<aspnet_User> users = showAllUsers().ToList();
            List<aspnet_User> tempUsers = showAllUsers().ToList();
            aspnet_User user = new aspnet_User();
            foreach (Permitted_user us in userId)
            {
                foreach (aspnet_User u in tempUsers)
                {
                    if (u.UserId == us.UserId)
                        users.Remove(u);
                }
            }
            return users;
        }

        /// <summary>
        /// Legger til tilatte brukere
        /// </summary>
        /// <param name="user">en tilatt bruker</param>
        public void addPermittedUsers(Permitted_user user)
        {
            aspnet_User phone = ( from u in db.aspnet_Users
                                where u.UserId == user.UserId
                                select u).FirstOrDefault();
            if (phone.MobilePhoneNumber != null)
            {
                string msg = "Hei! Du har blitt invitert til et chatroom. For å delta send \"hnd " + user.Chatroom + " start til 26112";
                SendSMS(phone.MobilePhoneNumber, msg);
            }
            db.Permitted_users.InsertOnSubmit(user);
            db.SubmitChanges();
        }

        /// <summary>
        /// Fjerner bruker fra ditt rom
        /// </summary>
        /// <param name="user">en tilatt bruker</param>
        public void deletePermittedUsers(Permitted_user user)
        {
            db.Permitted_users.DeleteOnSubmit(user);
            db.SubmitChanges();
        }

        /// <summary>
        /// Henter ut brukernavn basert på id
        /// </summary>
        /// <param name="userId">bruker id</param>
        /// <returns>brukernavn</returns>
        public string getUserName(Guid userId)
        {
            string username = (from u in db.aspnet_Users
                               where u.UserId == userId
                               select u.LoweredUserName).FirstOrDefault();

            return username;
        }

        /// <summary>
        /// Henter eier av ett chatroom
        /// </summary>
        /// <param name="room">ett chatroom</param>
        /// <returns>aspnet_User</returns>
        public aspnet_User getOwner(Chatroom room)
        {
            aspnet_User user = (from u in db.aspnet_Users
                                where u.UserId == room.OwnerId
                                select u).FirstOrDefault();
            return user;
        }

        /// <summary>
        /// Legger til ny rettighet
        /// </summary>
        /// <param name="usrInRole">den nye rettighetskollonen til bruker</param>
        public void addRole(aspnet_UsersInRole usrInRole)
        {
            db.aspnet_UsersInRoles.InsertOnSubmit(usrInRole);
            db.SubmitChanges();
        }

        /// <summary>
        /// Fjerner rettighet
        /// </summary>
        /// <param name="usrInRole">Rettighets kollonne</param>
        public void removeRole(aspnet_UsersInRole usrInRole)
        {
            db.aspnet_UsersInRoles.DeleteOnSubmit(usrInRole);
            db.SubmitChanges();
        }

        /// <summary>
        /// Returnerer inputbruker sin rolle(Rollen sier noe om hvilke rettigheter han har
        /// </summary>
        /// <param name="usr">Bruker kollonne</param>
        /// <returns></returns>
        public aspnet_UsersInRole getUserRoles(aspnet_User usr)
        {
            aspnet_UsersInRole usrInRole = (from u in db.aspnet_UsersInRoles
                                            where u.UserId.Equals(usr.UserId)
                                            select u).FirstOrDefault();
            return usrInRole;
        }

        /// <summary>
        /// Henter brukerid basert på tlf
        /// </summary>
        /// <param name="phoneNumber"></param>
        /// <returns></returns>
        public Guid GetUserIdFromPhone(string phoneNumber)
        {
            aspnet_User user = (from o in db.aspnet_Users
                                where o.MobilePhoneNumber == phoneNumber
                                select o).FirstOrDefault();

            return user.UserId;

        }

        /// <summary>
        /// Sender meldinger til alle deltakere som er innlogget via tlf.
        /// </summary>
        /// <param name="message"></param>
        public void SendSMSToPhoneParticipants(Message message)
        {
            //henter alle kollonner med "telefondeltakere" 
            List<aspnet_User> participants = (from u in db.UsersInChatrooms
                                         where u.chatId == message.Chatroom
                                         && u.ActiveOnPhone == "true"
                                         select u.aspnet_User).ToList();
            //Henter avsenders kolonne
            aspnet_User author = (from o in db.aspnet_Users
                                where o.UserId == message.AuthorId
                                select o).FirstOrDefault();

            foreach (aspnet_User s in participants)
                if(author.UserId != s.UserId)//Sender ikke melding til avsender da det er litt overflødig
                    SendSMS(s.MobilePhoneNumber, message.Chatroom + " " + author.UserName + " sa: " + message.Message1);

        }

        /// <summary>
        /// Sender SMS til parameter phoneNumber. Innholdet er text-parameter
        /// Blir rensket for Æ, Ø, Å da SMS-tjeneren ikke takler de bokstavene
        /// </summary>
        /// <param name="phoneNumber"></param>
        /// <param name="text"></param>
        public void SendSMS(string phoneNumber, string text)
        {
            //sms server fikser ikke æ, å eller å. Gjør derfor om
            text = text.Replace("æ", "ae");
            text = text.Replace("Æ", "AE");
            text = text.Replace("ø", "oe");
            text = text.Replace("Ø", "OE");
            text = text.Replace("å", "ao");
            text = text.Replace("Å", "AO");

            WebClient client = new WebClient();//Bruker webclient for å sende post forespørsel til sms-server
            NameValueCollection data = new NameValueCollection();

            data.Add("RCV", phoneNumber);
            data.Add("SND", "26112");
            data.Add("TXT", text);

            client.UploadValues("http://malmen.hin.no/pswin/sms/sendsms", data);
        }     
    }
}